package com.sunrise.gateway.web.core;

import com.aliyun.oss.model.ObjectMetadata;
import com.dap.commons.Constants;
import com.dap.exception.BusinessException;
import com.dap.exception.PlatformException;
import com.dap.oss.UploadService;
import com.dap.oss.config.OSSConfig;
import com.dap.param.ControlData;
import com.dap.param.ImportParam;
import com.dap.param.StringInput;
import com.dap.utils.ExcelUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;

/****
 * 导出excel请求转发核心功能
 * @author wangmin
 */
@Service
public class AsyncImportEngine extends EngineBase implements ExcelUtils.HandleExcelDataAsyncInterface {
    private final static Logger LOGGER = LoggerFactory.getLogger(AsyncImportEngine.class);

    public static class OtherParams {
        private final String validateGroupName;
        private final String importGroupName;
        private final Map<String, String> extraParam;
        private final ControlData ctrlData;
        public OtherParams(String validateGroupName, String importGroupName,
                Map<String, String> extraParam, ControlData ctrlData) {
            this.validateGroupName = validateGroupName;
            this.importGroupName = importGroupName;
            this.extraParam = extraParam;
            this.ctrlData = ctrlData;
        }
    }


    @Autowired
    public UploadService uploadService;
    @Autowired
    private OSSConfig ossConfig;

    private ServletFileUpload upload;

    public AsyncImportEngine() {
        super();

        DiskFileItemFactory factory = new DiskFileItemFactory();
        upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("utf-8");
    }


    public String execute(HttpServletRequest req) {
        // 获取参数 - 起始行, 从0开始
        int startRow = 1;
        String startRowStr = req.getParameter("startRow");
        if (!StringUtils.isEmpty(startRowStr)) {
            try {
                startRow = Integer.parseInt(startRowStr);
            } catch (Exception e) {
            }
        }

        // 获取参数 - 起始列, 从0开始
        int startCol = 0;
        String startColStr = req.getParameter("startCol");
        if (!StringUtils.isEmpty(startColStr)) {
            try {
                startCol = Integer.parseInt(startColStr);
            } catch (Exception e) {
            }
        }

        // 获取参数 - 验证接口
        String validateGroupName = req.getParameter("validateGroupName");
        if (StringUtils.isEmpty(validateGroupName)) {
            throw new BusinessException(Constants.ResponseCode.GENERAL_EXCEPTION, "未指定验证接口");
        }

        // 获取参数 - 导入接口
        String importGroupName = req.getParameter("importGroupName");
        if (StringUtils.isEmpty(importGroupName)) {
            throw new BusinessException(Constants.ResponseCode.GENERAL_EXCEPTION, "未指定导入接口");
        }


        // 获取额外参数
        Map<String, String> extraParam = new HashMap<>();
        Enumeration pn = req.getParameterNames();
        while (pn.hasMoreElements()) {
            String parameterName = (String) pn.nextElement();
            String value = req.getParameter(parameterName);
            extraParam.put(parameterName, value);
        }


        // 生成输入参数
        ImportParam importParam = new ImportParam(null, extraParam);
        StringInput stringInput = new StringInput(importParam);
        fillSessionInfoIntoCtrlDataInterface.fill(stringInput, importGroupName, req);
        OtherParams otherParams = new OtherParams(validateGroupName, importGroupName, extraParam, stringInput.getCtrlData());


        // 读取并解析excel
        try {
            List<FileItem> items = upload.parseRequest(req);
            for (FileItem item : items) {//遍历所有客户端提交的参数(包括文件域)
                if (!item.isFormField()) {
                    InputStream inputStream = item.getInputStream();

                    // 获取后缀
                    String extension = Constants.EXCEL_EXTENSION_XLS;
                    String itemName = item.getName();
                    if (!StringUtils.isEmpty(itemName)) {
                        int extensionIdx = itemName.lastIndexOf('.');
                        if (extensionIdx >= 0) {
                            extension = itemName.substring(extensionIdx);
                        }
                    }

                    ExcelUtils.handleExcelAsync(inputStream, extension, startRow, startCol, this, otherParams);

                    item.delete();

                    break;
                }
            }
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.warn("", e);
            throw new PlatformException(Constants.ResponseCode.FILE_UPLOAD_FAILURE);
        }


        return "null";
    }


    @Override
    public void validateExcelData(Object content, Object otherParams) {
        OtherParams op = (OtherParams) otherParams;

        ImportParam importParam = new ImportParam(content, op.extraParam);
        StringInput input = new StringInput(op.ctrlData, importParam);

        String importTaskId = executeRequestStr(op.validateGroupName, input, true);
        op.extraParam.put("importTaskId", importTaskId);
    }
    @Override
    public String uploadTempFile(String fileName, byte[] bytes) {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setExpirationTime(new Date(System.currentTimeMillis() + 24 * 3600 * 1000));
        uploadService.putObject(ossConfig.getBucket(), fileName, bais, objectMetadata);

        return ossConfig.resolveFullUrl(fileName);
    }
    @Override
    public Object importExcelData(Object content, Object otherParams) {
        OtherParams op = (OtherParams) otherParams;

        ImportParam importParam = new ImportParam(content, op.extraParam);
        StringInput input = new StringInput(op.ctrlData, importParam);

        return executeRequestStr(op.importGroupName, input, true);
    }
    @Override
    public String removeUploadedTempFile(List<String> fileNames) {
        uploadService.removeObject(ossConfig.getBucket(), fileNames);
        return null;
    }
}
